package com.wq.jdk8;

import java.util.concurrent.*;

/**
 * @Author: wangqiang20995
 * @Date:2019/7/10
 * @Description:
 * @Resource:
 */
public class ExecutorServiceDemo {
    public static boolean beginChange = false;

    public static void main(String args[]) {
        ExecutorService executorService = new ThreadPoolExecutor(5, 100, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<>(1));
        ((ThreadPoolExecutor) executorService).prestartAllCoreThreads();

        CountDownLatch monitor = new CountDownLatch(5);

        Runner runner = new Runner(monitor);

        for (int i = 0; i < 5; i++) {
            executorService.execute(runner);
        }

        try {
            TimeUnit.SECONDS.sleep(10);
        } catch (InterruptedException e) {
            System.out.println("Main error:" + e.getMessage());
        }

        while (true){
            if(beginChange){
                ThreadPoolExecutor executor = (ThreadPoolExecutor) executorService;
                //如果设置的时候，所有的worker都在执行任务，那么根据ThreadPoolExecutor#interruptIdleWorkers方法，遍历Workers(hashSet)的时候会获取独占不可重入锁失败
                //那么就不会中断这个worker绑定的thread，当worker执行完runnable之后，worker的实际数量还是大于corePoolSize
                //只有等这些worker都执行完了runnable，然后阻塞在getTask上，并等待keepAliveTimes，仍旧无法从queue中获取到runnable，此时它才会自动从workers中remove worker
                //如果之前执行中断时都在执行任务的worker此时全部空闲了，执行完了Runnable，那么此时worker的个数就是core个
                executor.setCorePoolSize(3);
                break;
            }
        }

        try {
            //当所有的线程执行任务完毕，开始下一步操作
            monitor.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        int core = ((ThreadPoolExecutor) executorService).getCorePoolSize();

        System.out.println("core:" + core);
        System.out.println(runner.getI());

        executorService.shutdown();
    }
}

class Runner implements Runnable {

    private int i;

    private CountDownLatch countDownLatch;

    public Runner(CountDownLatch countDownLatch){
        this.countDownLatch = countDownLatch;
    }

    @Override
    public void run() {
        i++;
        System.out.println(Thread.currentThread().getName() + "-->" + i);
//        int s = i / 0;
        try {
            //这个runnable由ThreadPoolExecutor中的Worker执行，执行期间，worker（extends from AQS会lock住），然后另外一个线程(可以是main)去修改线程池的参数
            //线程池的参数修改了之后会获取每个Worker，然后lock，再设置中断，但是这些worker都是等待获取task去执行的worker，不包含正在执行的worker


            /**
             * ThreadPoolExecutor#addWorker(Runnable runnable,boolean core)
             * core参数=true，并不是代表将runnable标记为core线程，而是以这个作为判断依据
             * 当前线程池中的worker数目wc，wc > (core ? corePoolSize : maximumPoolSize)
             * 也就是说core=true，如果wc>core，那就直接addWorker返回false，不创建worker，直接塞入阻塞队列queue中
             * 如果core=false，那么进行后续的判断逻辑，是要加入阻塞队列(阻塞队列未满)还是直接创建Worker(阻塞队列已满)
             */
            ExecutorServiceDemo.beginChange = true;
            Thread.sleep(1);
            countDownLatch.countDown();
        } catch (InterruptedException e) {
            System.out.println("[" + Thread.currentThread().getName() + "]error:" + e.getMessage());
        }
    }

    public int getI() {
        return i;
    }
}
